﻿using QInjection.Injector.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QInjection.Injector.Instructors
{
    public class UnaryInstructor : INodesInstructor
    {
        private List<Node> _nodesmap;
        private Dictionary<Node, List<Branch>> _branchesmap;
        private Dictionary<Node, List<Tuple<Restriction, object>>> _restrictionsmap;

        public UnaryInstructor()
        {
            _nodesmap = new List<Node>();
            _nodesmap.Add(Node.PrefixUnaryExpression);
            _nodesmap.Add(Node.PostfixUnaryExpression);
            _nodesmap.Add(Node.IdentifierName);
            _nodesmap.Add(Node.LiteralExpression);
            _nodesmap.Add(Node.ParenthesizedExpression);

            _branchesmap = new Dictionary<Node, List<Branch>>();
            foreach (var n in _nodesmap)
            {
                _branchesmap[n] = new List<Branch>();
                _branchesmap[n].Add(Branch.Body);
                _branchesmap[n].Add(Branch.Expression);
            }

            _restrictionsmap = new Dictionary<Node, List<Tuple<Restriction, object>>>();

            _restrictionsmap[Node.PrefixUnaryExpression] = new List<Tuple<Restriction, object>>();
            _restrictionsmap[Node.PrefixUnaryExpression].Add(new Tuple<Restriction, object>(Restriction.Operator, Operator.LogicalNot));
            _restrictionsmap[Node.PrefixUnaryExpression].Add(new Tuple<Restriction, object>(Restriction.Operator, Operator.PlusPlus));
            _restrictionsmap[Node.PrefixUnaryExpression].Add(new Tuple<Restriction, object>(Restriction.Operator, Operator.MinusMinus));
            _restrictionsmap[Node.PrefixUnaryExpression].Add(new Tuple<Restriction, object>(Restriction.Operator, Operator.BitwiseComplement));

            _restrictionsmap[Node.PostfixUnaryExpression] = new List<Tuple<Restriction, object>>();
            _restrictionsmap[Node.PostfixUnaryExpression].Add(new Tuple<Restriction, object>(Restriction.Operator, Operator.LogicalNot));
            _restrictionsmap[Node.PostfixUnaryExpression].Add(new Tuple<Restriction, object>(Restriction.Operator, Operator.PlusPlus));
            _restrictionsmap[Node.PostfixUnaryExpression].Add(new Tuple<Restriction, object>(Restriction.Operator, Operator.MinusMinus));
            _restrictionsmap[Node.PostfixUnaryExpression].Add(new Tuple<Restriction, object>(Restriction.Operator, Operator.BitwiseComplement));
        }
        public IEnumerable<Node> Nodes
        {
            get { return _nodesmap; }
        }

        public IEnumerable<Branch> Branches(Node node)
        {
            if (_branchesmap.ContainsKey(node))
                return _branchesmap[node];
            else
                return new List<Branch>();
        }

        public IEnumerable<Tuple<Restriction, object>> Restrictions(Node node)
        {
            if (_restrictionsmap.ContainsKey(node))
                return _restrictionsmap[node];
            else
                return new List<Tuple<Restriction, object>>();
        }
    }
}
